import gradio as gr
import tempfile
import os
import time
from datetime import datetime
import requests
import json
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 配置 SiliconFlow API
SILICONFLOW_API_URL = "https://api.siliconflow.cn/v1/audio/speech"
API_KEY = os.getenv('SILICONFLOW_API_KEY')

if not API_KEY:
    raise ValueError("""
        请设置 SILICONFLOW_API_KEY 环境变量！
        
        可以通过以下方式之一设置：
        1. 创建 .env 文件并添加：
           SILICONFLOW_API_KEY=your-api-key-here
           
        2. 直接设置环境变量：
           export SILICONFLOW_API_KEY=your-api-key-here
    """)

# 说话人配置 - 更新为系统预置音色
SPEAKERS = [
    ("沉稳男声 (alex)", "FunAudioLLM/CosyVoice2-0.5B:alex"),
    ("低沉男声 (benjamin)", "FunAudioLLM/CosyVoice2-0.5B:benjamin"),
    ("磁性男声 (charles)", "FunAudioLLM/CosyVoice2-0.5B:charles"),
    ("欢快男声 (david)", "FunAudioLLM/CosyVoice2-0.5B:david"),
    ("沉稳女声 (anna)", "FunAudioLLM/CosyVoice2-0.5B:anna"),
    ("激情女声 (bella)", "FunAudioLLM/CosyVoice2-0.5B:bella"),
    ("温柔女声 (claire)", "FunAudioLLM/CosyVoice2-0.5B:claire"),
    ("欢快女声 (diana)", "FunAudioLLM/CosyVoice2-0.5B:diana")
]

# 预设文本示例
TEXT_EXAMPLES = [
    ["今天天气真不错，阳光明媚，让人心情愉悦。"],
    ["欢迎使用SiliconFlow的文本转语音系统，我是您的AI语音助手。"],
    ["The quick brown fox jumps over the lazy dog."]
]

class TTSGenerator:
    def __init__(self, api_key):
        self.api_key = api_key
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        self.output_dir = "generated_audio"
        os.makedirs(self.output_dir, exist_ok=True)
    
    def generate_tts(self, text, voice, speed=1.0, volume=1.0, 
                    sample_rate=44100, format="wav", language=None):
        """
        调用 SiliconFlow API 进行文本转语音
        Args:
            text (str): 要转换的文本
            voice (str): 音色ID
            speed (float): 语速，范围 0.25-4.0
            volume (float): 音量，范围 0.1-5.0
            sample_rate (int): 采样率，支持 8000, 16000, 24000, 44100, 48000
            format (str): 音频格式，支持 wav, mp3, ogg
            language (str, optional): 指定语言，如 zh, en, ja, ko
        """
        data = {
            "model": "FunAudioLLM/CosyVoice2-0.5B",
            "input": text,
            "voice": voice,
            "speed": float(speed),
            "volume": float(volume),
            "response_format": format,
            "sample_rate": int(sample_rate)
        }
        
        # 如果指定了语言，添加到请求中
        if language:
            data["language"] = language
        
        try:
            # 打印请求信息以便调试
            print(f"Request URL: {SILICONFLOW_API_URL}")
            print(f"Request Headers: {self.headers}")
            print(f"Request Data: {json.dumps(data, ensure_ascii=False)}")
            
            response = requests.post(
                SILICONFLOW_API_URL, 
                headers=self.headers, 
                json=data,
                stream=False
            )
            
            # 打印响应信息以便调试
            print(f"Response Status Code: {response.status_code}")
            print(f"Response Headers: {response.headers}")
            
            if response.status_code == 200:
                return response.content
            else:
                try:
                    error_data = response.json()
                    error_msg = error_data.get('error', {}).get('message', '未知错误')
                except:
                    error_msg = response.text
                raise Exception(f"API调用失败 (HTTP {response.status_code}): {error_msg}")
                
        except requests.exceptions.RequestException as e:
            raise Exception(f"API请求失败: {str(e)}")
        except Exception as e:
            raise Exception(f"处理失败: {str(e)}")

def text_to_speech(text, voice, speed=1.0, volume=1.0, 
                  sample_rate=44100, format="wav", language=None):
    """
    文本转语音的核心函数
    """
    if not text.strip():
        return None, "错误：请输入文本内容"
    
    try:
        start_time = time.time()
        generator = TTSGenerator(API_KEY)
        audio_data = generator.generate_tts(
            text=text,
            voice=voice,
            speed=speed,
            volume=volume,
            sample_rate=sample_rate,
            format=format,
            language=language
        )
        
        # 生成文件名
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"tts_{timestamp}.{format}"
        filepath = os.path.join(generator.output_dir, filename)
        
        with open(filepath, "wb") as f:
            f.write(audio_data)
            
        process_time = time.time() - start_time
        return filepath, f"""✅ 生成成功！
处理时间: {process_time:.2f}秒
保存位置: {filepath}
采样率: {sample_rate}Hz
格式: {format}"""
    
    except Exception as e:
        return None, f"❌ 错误：{str(e)}"

# 音频格式选项
AUDIO_FORMATS = [
    ("WAV", "wav"),
    ("MP3", "mp3"),
    ("OGG", "ogg")
]

# 采样率选项
SAMPLE_RATES = [
    ("8kHz", 8000),
    ("16kHz", 16000),
    ("24kHz", 24000),
    ("44.1kHz", 44100),
    ("48kHz", 48000)
]

# 语言选项
LANGUAGES = [
    ("自动检测", None),
    ("中文", "zh"),
    ("英文", "en"),
    ("日语", "ja"),
    ("韩语", "ko")
]

# 创建自定义CSS样式
custom_css = """
.container {
    max-width: 850px;
    margin: auto;
    padding: 20px;
}
.output-message {
    font-weight: bold;
    white-space: pre-wrap;
}
"""

# 创建 Gradio 界面
with gr.Blocks(css=custom_css, title="SiliconFlow TTS") as demo:
    gr.Markdown("""
    # 🎙️ SiliconFlow 文本转语音系统
    
    基于 SiliconFlow 平台的高性能文本转语音服务。
    
    ### 特性：
    - 支持多种预置音色
    - 跨语言语音合成（中文、英文、日语、韩语等）
    - 支持情感控制和语速调节
    - 自动保存生成的音频文件
    
    ### 使用说明：
    1. 在文本框中输入要转换的文本
    2. 选择预置音色并调整语音参数
    3. 点击"生成语音"按钮
    4. 生成的音频文件将保存在 generated_audio 目录
    """)
    
    with gr.Row():
        with gr.Column():
            text_input = gr.Textbox(
                label="输入文本",
                placeholder="请输入要转换的文本...\n支持中文、英文、日语、韩语等",
                lines=5
            )
            
            with gr.Row():
                voice = gr.Dropdown(
                    choices=SPEAKERS,
                    label="选择音色",
                    value=SPEAKERS[0][1]
                )
                language = gr.Dropdown(
                    choices=LANGUAGES,
                    label="语言",
                    value=None
                )
            
            with gr.Row():
                speed = gr.Slider(
                    minimum=0.25,
                    maximum=4.0,
                    step=0.1,
                    label="语速",
                    value=1.0
                )
                volume = gr.Slider(
                    minimum=0.1,
                    maximum=5.0,
                    step=0.1,
                    label="音量",
                    value=1.0
                )
            
            with gr.Row():
                format = gr.Dropdown(
                    choices=AUDIO_FORMATS,
                    label="音频格式",
                    value="wav"
                )
                sample_rate = gr.Dropdown(
                    choices=SAMPLE_RATES,
                    label="采样率",
                    value=44100
                )
            
            generate_btn = gr.Button("生成语音", variant="primary")
            
            audio_output = gr.Audio(label="生成的语音")
            status_output = gr.Textbox(
                label="状态信息",
                interactive=False,
                elem_classes=["output-message"]
            )
    
    gr.Examples(
        examples=TEXT_EXAMPLES,
        inputs=text_input,
        label="示例文本"
    )
    
    generate_btn.click(
        fn=text_to_speech,
        inputs=[
            text_input, voice, speed, volume,
            sample_rate, format, language
        ],
        outputs=[audio_output, status_output]
    )

if __name__ == "__main__":
    try:
        # 设置 server_name="0.0.0.0" 允许局域网访问
        # share=False 不创建公共链接
        demo.launch(
            server_name="0.0.0.0",  # 允许局域网访问
            server_port=7860,       # 指定端口号
            share=False,            # 不创建公共链接
            show_error=True         # 显示详细错误信息
        )
    except Exception as e:
        print(f"启动服务器时出错: {str(e)}")